#include "StdAfx.h"
#include "TString.h"
#include <Windows.h>


const wchar_t* _TStrBase::AnsiToUnicode(__in unsigned int CodePage, __in const char* pszSrc, __out std::wstring &wstrDes)
{
	int nNum;

	//ASSERT( pszSrc != NULL );
	if ( pszSrc == NULL ) {
		return NULL;
	}

	nNum = MultiByteToWideChar (CodePage, 0, pszSrc, -1, NULL, 0);
	if ( nNum <= 0 ) {
		return NULL;
	}

	wchar_t* lpszBuff = new wchar_t[nNum];
	if ( lpszBuff == NULL ) {
		return NULL;
	}

	nNum = MultiByteToWideChar (CodePage, 0, pszSrc, -1, lpszBuff, nNum);
	if ( nNum <= 0 ) {
		delete[] lpszBuff;
		return NULL;
	}

	wstrDes = wstring(lpszBuff);
	delete[] lpszBuff;

	return wstrDes.c_str();
}

const char* _TStrBase::UnicodeToAnsi(__in unsigned int CodePage, __in const wchar_t* lpszSrc, __out std::string &strDes)
{
	int nNum;

	//ASSERT( lpszSrc != NULL );
	if ( lpszSrc == NULL ) {
		return NULL;
	}

	nNum = WideCharToMultiByte (CodePage, 0, lpszSrc, -1, NULL, 0, NULL, NULL);
	if ( nNum <= 0 ) {
		return NULL;
	}

	char* pszBuff = new char[nNum];
	if ( pszBuff == NULL ) {
		return NULL;
	}

	nNum = WideCharToMultiByte (CodePage, 0, lpszSrc, -1, pszBuff, nNum, NULL, NULL);
	if ( nNum <= 0 ) {
		delete[] pszBuff;
		return NULL;
	}

	strDes = string(pszBuff);
	delete[] pszBuff;

	return strDes.c_str();
}

const char* _TStrBase::AnsiToUtf8(__in unsigned int CodePage, __in const char* pszSrc, __out std::string &strUtf8)
{
	wstring wstr;
	AnsiToUnicode(CodePage, pszSrc, wstr);

	return UnicodeToAnsi(CP_UTF8, wstr.c_str(), strUtf8);
}

const char* _TStrBase::Utf8ToAnsi(__in unsigned int CodePage, __in const char* pszUtf8, __out std::string &strAnsi)
{
	wstring wstr;
	AnsiToUnicode(CodePage, pszUtf8, wstr);

	return UnicodeToAnsi(CP_ACP, wstr.c_str(), strAnsi);
}


const char* _TStrBase::TSB_ToUpper(__inout std::string &strUpper) {
	CharUpperBuffA((char*)strUpper.c_str(), strUpper.length()+1);
	return strUpper.c_str();
}

const wchar_t* _TStrBase::TSB_ToUpper(__inout std::wstring &strUpper) {
	CharUpperBuffW((wchar_t*)strUpper.c_str(), strUpper.length()+1);
	return strUpper.c_str();
}

const char* _TStrBase::TSB_ToLower(__inout std::string &strLower) {
	CharLowerBuffA((char*)strLower.c_str(), strLower.length()+1);
	return strLower.c_str();
}

const wchar_t* _TStrBase::TSB_ToLower(__inout std::wstring &strLower) {
	CharLowerBuffW((wchar_t*)strLower.c_str(), strLower.length()+1);
	return strLower.c_str();
}


const char* __cdecl _TStrBase::TSB_FormatA(__out string& strResult, __in const char* pszFormat, __in va_list argList)
{
	int nLength = _vscprintf( pszFormat, argList );
	if ( nLength <= 0 ) {
		return NULL;
	}

	char* pszBuff = new char[nLength+1];
	if ( pszBuff == NULL ) {
		return NULL;
	}

	vsprintf_s(pszBuff, nLength+1, pszFormat, argList);

	strResult = pszBuff;
	delete[] pszBuff;
	
	return strResult.c_str();
}

const wchar_t* __cdecl _TStrBase::TSB_FormatW(__out wstring& strResult, __in const wchar_t* pszFormat, __in va_list argList)
{
	int nLength = _vscwprintf( pszFormat, argList );
	if ( nLength <= 0 ) {
		return NULL;
	}

	wchar_t* pszBuff = new wchar_t[nLength+1];
	if ( pszBuff == NULL ) {
		return NULL;
	}

	vswprintf_s(pszBuff, nLength+1, pszFormat, argList);

	strResult = pszBuff;
	delete[] pszBuff;

	return strResult.c_str();
}

unsigned int _TStrBase::TSB_Find(__in const string& strDes, 
							   __in const char* lpszSrc, 
							   __in const unsigned int& nStartPos, 
							   __in const bool& bNotCaseSensitive
							   )
{
	if ( strDes.empty() || lpszSrc == NULL || nStartPos >= strDes.size() ) {
		return -1;
	}

	LPCSTR lpszStart = strDes.c_str() + nStartPos;
	LPSTR lpszFind = bNotCaseSensitive ? StrStrIA(lpszStart, lpszSrc) : StrStrA(lpszStart, lpszSrc);
	if ( lpszFind == NULL ) {
		return -1;
	}

	return lpszFind - lpszStart + nStartPos;
}

unsigned int _TStrBase::TSB_Find(__in const wstring& strDes, 
							   __in const wchar_t* lpszSrc, 
							   __in const unsigned int& nStartPos, 
							   __in const bool& bNotCaseSensitive
							   )
{
	if ( strDes.empty() || lpszSrc == NULL || nStartPos >= strDes.size() ) {
		return -1;
	}

	LPCWSTR lpszStart = strDes.c_str() + nStartPos;
	LPWSTR lpszFind = bNotCaseSensitive ? StrStrIW(lpszStart, lpszSrc) : StrStrW(lpszStart, lpszSrc);
	if ( lpszFind == NULL ) {
		return -1;
	}

	return lpszFind - lpszStart + nStartPos;
}

unsigned int _TStrBase::TSB_Find(__in const string& strDes, 
							   __in const char& cSrc, 
							   __in const unsigned int& nStartPos, 
							   __in const bool& bNotCaseSensitive
							   )
{
	if ( strDes.empty() || nStartPos >= strDes.size() ) {
		return -1;
	}

	LPCSTR lpszStart = strDes.c_str() + nStartPos;
	LPSTR lpszFind = bNotCaseSensitive ? StrChrIA(lpszStart, cSrc) : StrChrA(lpszStart, cSrc);
	if ( lpszFind == NULL ) {
		return -1;
	}

	return lpszFind - lpszStart + nStartPos;
}

unsigned int _TStrBase::TSB_Find(__in const wstring& strDes, 
							   __in const wchar_t& cSrc, 
							   __in const unsigned int& nStartPos, 
							   __in const bool& bNotCaseSensitive
							   )
{
	if ( strDes.empty() || nStartPos >= strDes.size() ) {
		return -1;
	}

	LPCWSTR lpszStart = strDes.c_str() + nStartPos;
	LPWSTR lpszFind = bNotCaseSensitive ? StrChrIW(lpszStart, cSrc) : StrChrW(lpszStart, cSrc);
	if ( lpszFind == NULL ) {
		return -1;
	}

	return lpszFind - lpszStart + nStartPos;
}